/**
 * @file HLSRecord.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2020-09-21
 * 
 * @copyright Copyright Julong 2020
 * 
 */

#ifndef _HLS_RECORD_H_
#define _HLS_RECORD_H_

#include <string>
#include <vector>

#ifdef __cplusplus
extern "C"
{
#endif
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif

namespace GBXUEAN
{
    class HLSRecord
    {
    public:
        typedef struct Option_t
        {
            uint32_t streamId;  // 流ID
            std::string prefix; // 存储路径前缀
            double duration;    // 切片大小（秒）
            uint32_t sequence;  //起始序号
            Option_t()
            {
                duration = 10.f; // 10s
                sequence = 0;
            }
        } Option;

    public:
        static void configurationinfo();
        static void log_packet(const AVFormatContext *fmt_ctx, AVPacket *pkt, const char *tag);

    public:
        HLSRecord(HLSRecord::Option option);
        ~HLSRecord() = default;
        int start(const AVFormatContext *ifmtCtx);
        int onPacket(AVPacket *packet);
        void stop();

    private:
        uint32_t m_streamId;
        std::string m_prefix;
        double m_duration;
        uint32_t m_sequence;

    private:
        bool m_isWork;
        int m_output_packet_index;
        int64_t m_start_pts;
        int64_t m_start_dts;
        AVFormatContext *m_ofmtCtx;
        int m_video_input_stream_index;
        int m_audio_input_stream_index;
        int m_video_output_stream_index;
        int m_audio_output_stream_index;
        AVRational m_video_time_base;
        AVRational m_audio_time_base;

    private: // 临时记录packet信息
        int m_packet_stream_index;
        int64_t m_packet_pts;
        int64_t m_packet_dts;
        int64_t m_packet_duration;
        int64_t m_packet_pos;

    private: // 临时记录packet信息
        void recordPacketInfo(AVPacket *packet)
        {
            m_packet_stream_index = packet->stream_index;
            m_packet_pts = packet->pts;
            m_packet_dts = packet->dts;
            m_packet_duration = packet->duration;
            m_packet_pos = packet->pos;
        };
        void recoveryPacketInfo(AVPacket *packet)
        {
            packet->stream_index = m_packet_stream_index;
            packet->pts = m_packet_pts;
            packet->dts = m_packet_dts;
            packet->duration = m_packet_duration;
            packet->pos = m_packet_pos;
        };

    private: // 路径生成
        std::string m_streamName;
        std::string m_livePath;
        std::string m_liveM3u8FilePath;
        std::string m_currentHour;
        std::string m_currentDateName;
        std::string m_currentDateTimeName;
        std::string m_currentPath;
        std::string m_currentSequenceName;
        std::string m_currentFileName;
        std::string m_currentLiveFileName;
        std::string m_currentMpegTSFilePath;
        std::string m_currentM3u8FilePath;
        std::string getNextPath();

    private:
        typedef struct RecordInfo_t
        {
            std::string sequenceName;
            std::string recordRelativePath;
            std::string liveRelativePath;
            double duration;
        } RecordInfo;
        std::vector<HLSRecord::RecordInfo> m_liveList;
        std::vector<HLSRecord::RecordInfo> m_recordList;
        int writeM3u8();
        int wirteLiveM3u8();
        int wirteRecordM3u8();
    };
} // namespace GBXUEAN

#endif //_HLS_RECORD_H_